package com.quarkus.resource;

import com.quarkus.model.Fruit;
import io.vertx.core.json.JsonObject;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;

import javax.inject.Inject;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 *  使用Rest api 实现访问
 */
@Path("h/fruit")
@Produces(MediaType.APPLICATION_JSON)
public class FruitHighLeveResource {

    @Inject
    RestClient restClient;

    @Inject
    RestHighLevelClient restHighLevelClient;

    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    public IndexResponse add(Fruit fruit) throws IOException {

        var postRequest = new IndexRequest("fruit");

        postRequest.id(fruit.id);
        postRequest.source(JsonObject.mapFrom(fruit).toString(), XContentType.JSON);

        var response = restHighLevelClient.index(postRequest, RequestOptions.DEFAULT);

        return response;
    }

    @GET
    @Path("{id}")
    public Fruit fruit(@PathParam("id") String id) throws IOException {
        var request = new GetRequest("fruit", id);

        var response = restHighLevelClient.get(request, RequestOptions.DEFAULT);

        return JsonObject.mapFrom(response.getSource()).mapTo(Fruit.class);
    }

    @GET
    @Path("query/color/{color}")
    public List<Fruit> searchByColor(@PathParam("color") String color) throws IOException {
        return search("color", color);
    }

    @GET
    @Path("query/name/{name}")
    public List<Fruit> searchByName(@PathParam("name") String name) throws IOException {
        return search("name", name);
    }

    private List<Fruit> search(String term, String match) throws IOException {
        var request = new SearchRequest("fruit");

        var searchSource = new SearchSourceBuilder();
        searchSource.query(QueryBuilders.matchQuery(term, match));

        request.source(searchSource);

        var responseBody = restHighLevelClient.search(request, RequestOptions.DEFAULT);

        var hits = responseBody.getHits();

        List<Fruit> results = new ArrayList<>(hits.getHits().length);
        for (SearchHit hit : hits.getHits()) {
            String sourceAsString = hit.getSourceAsString();
            JsonObject json = new JsonObject(sourceAsString);
            results.add(json.mapTo(Fruit.class));
        }

        return results;
    }


}
